/*
 * Copyright (c) 2015. For Intelligent Group.
 */

package com.intelligent.ispc.web.controller;

import com.google.common.collect.Lists;
import com.intelligent.ispc.common.dto.JsonPageResponseDto;
import com.intelligent.ispc.common.dto.JsonResponseDto;
import com.intelligent.ispc.common.mapper.JsonMapper;
import com.intelligent.ispc.common.utils.ApplicationException;
import com.intelligent.ispc.common.utils.ExceptionMessages;
import com.intelligent.ispc.common.web.Servlets;
import com.intelligent.ispc.core.dto.BaseDto;
import com.intelligent.ispc.core.dto.StationDto;
import com.intelligent.ispc.core.dto.TestItemDto;
import com.intelligent.ispc.core.service.SpcAnalysisService;
import com.intelligent.ispc.core.service.SpcExportService;
import com.intelligent.ispc.external.rcall.dto.ControlDataDto;
import com.intelligent.ispc.external.rcall.dto.NormalDistributionDto;
import com.intelligent.ispc.utils.Constant;
import com.intelligent.ispc.utils.SystemConfig;
import com.intelligent.ispc.web.utils.PageUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.ServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by Peter.Li on 2015/10/21.
 */
@Controller
@RequestMapping(value = "/analysis")
public class SpcAnalysisController {

    @Autowired
    private SpcAnalysisService spcAnalysisService;

    @Autowired
    private SpcExportService spcExportService;

    @Autowired
    private SystemConfig systemConfig;

    protected JsonMapper mapper = JsonMapper.nonDefaultMapper();

    @RequestMapping(value = "/spc", method = RequestMethod.GET)
    public String navSpc(Model model, ServletRequest request) {
        Subject subject = SecurityUtils.getSubject();
        if (!subject.isPermitted("analysis:spc:view")) {
            return "error/noPermission";
        }
        return "analysis/spc/spcAnalysis";
    }

    @ResponseBody
    @RequestMapping(value = "/stations")
    public JsonResponseDto stations(String projectId, Model model) {
        List<StationDto> list = spcAnalysisService.findStationByProject(projectId);

        return JsonResponseDto.SUCCESS().setBody(list);
    }

    @ResponseBody
    @RequestMapping(value = "/testData")
    public JsonPageResponseDto items(ServletRequest request, Model model) {
        Subject subject = SecurityUtils.getSubject();
        if (!subject.isPermitted("analysis:spc:view")) {
            return JsonPageResponseDto.FAILURE().setMessage(ExceptionMessages.EXCEPTION_NO_PERMISSION);
        }
        Map<String, Object> searchParam = Servlets.getParametersStartingWith(request, "search_");

        Page<TestItemDto> page = spcAnalysisService.searchTestItem(searchParam, PageUtil.buildPageWithParameters(request, systemConfig.getPageSize()));
        List<TestItemDto> list = page.getContent();

        JsonPageResponseDto json = JsonPageResponseDto.SUCCESS().setBody(list);
        json.setRecordsTotal(page.getTotalElements());
        json.setRecordsFiltered(page.getTotalElements());
        json.setDraw(0);

        return json;
    }

    @ResponseBody
    @RequestMapping(value = "/saveTestDataCache")
    public JsonResponseDto saveCache(ServletRequest request, Model model) {
        boolean hasExclude = false;
        try {
            Subject subject = SecurityUtils.getSubject();
            if (!subject.isPermitted("analysis:spc:view")) {
                return JsonResponseDto.FAILURE().setMessage(ExceptionMessages.EXCEPTION_NO_PERMISSION);
            }
            Map<String, Object> searchParam = Servlets.getParametersStartingWith(request, "search_");

            if (searchParam.containsKey("filterCache")) {
                String cache = (String) searchParam.get("filterCache");
                JsonMapper mapper = new JsonMapper();
                Map<String, Object> paramCache = mapper.fromJson(cache, mapper.contructMapType(Map.class, String.class, Object.class));
                Map<String, Object> param = this.getParameters(searchParam);
                if (paramCache.containsKey("isAllCheck")) {
                    param.put("isAllCheck", paramCache.get("isAllCheck"));
                }

                if (paramCache.containsKey("checkType")) {
                    param.put("checkType", paramCache.get("checkType"));
                }

                if (paramCache.containsKey("filterValue")) {
                    param.put("filterValue", paramCache.get("filterValue"));
                }
                spcAnalysisService.saveExcludeIds(param);
            }

            hasExclude = spcAnalysisService.saveExcludeIds(searchParam);

        } catch (ApplicationException ex) {
            return JsonResponseDto.FAILURE().setMessage(ex.getMessage());
        }
        return JsonResponseDto.SUCCESS().setBody(hasExclude);
    }

    private Map<String, Object> getParameters(Map<String, Object> searchParams) {

        Map<String, Object> map = new HashMap<String, Object>();


        if (searchParams.containsKey("projectId")) {
            map.put("projectId", searchParams.get("projectId"));
        }

        if (searchParams.containsKey("itemName")) {
            map.put("itemName", searchParams.get("itemName"));
        }

        if (searchParams.containsKey("serialNumber")) {
            map.put("serialNumber", searchParams.get("serialNumber"));
        }

        if (searchParams.containsKey("startTime")) {
            map.put("startTime", searchParams.get("startTime"));
        }

        if (searchParams.containsKey("stopTime")) {
            map.put("stopTime", searchParams.get("stopTime"));
        }

        if (searchParams.containsKey("stationIdOrSlotNo")) {
            map.put("stationIdOrSlotNo", searchParams.get("stationIdOrSlotNo"));
        }
        return map;
    }

    @ResponseBody
    @RequestMapping(value = "/resetTestDataCache")
    public JsonResponseDto invalidateCacheExcludeIds(ServletRequest request, Model model) {
        try {
            Subject subject = SecurityUtils.getSubject();
            if (!subject.isPermitted("analysis:spc:view")) {
                return JsonResponseDto.FAILURE().setMessage(ExceptionMessages.EXCEPTION_NO_PERMISSION);
            }
            Map<String, Object> searchParam = Servlets.getParametersStartingWith(request, "search_");
            spcAnalysisService.invalidateCacheExcludeIds(searchParam);
        } catch (ApplicationException ex) {
            return JsonResponseDto.FAILURE().setMessage(ex.getMessage());
        }
        return JsonResponseDto.SUCCESS();
    }

    @ResponseBody
    @RequestMapping(value = "/distinctItems")
    public JsonResponseDto distinctItems(ServletRequest request, Model model) {
        List<BaseDto> list = null;
        try {
            Subject subject = SecurityUtils.getSubject();
            if (!subject.isPermitted("analysis:spc:view")) {
                return JsonResponseDto.FAILURE().setMessage(ExceptionMessages.EXCEPTION_NO_PERMISSION);
            }

            Map<String, Object> searchParam = Servlets.getParametersStartingWith(request, "search_");
            list = spcAnalysisService.searchDistinctTestItem(searchParam);

        } catch (ApplicationException ex) {
            return JsonResponseDto.FAILURE().setMessage(ex.getMessage());
        }

        return JsonResponseDto.SUCCESS().setBody(list);
    }

    @ResponseBody
    @RequestMapping(value = "/distinctItemsPage")
    public JsonPageResponseDto distinctItemsP(ServletRequest request, Model model) {
        Page<BaseDto> page = null;
        try {
            Subject subject = SecurityUtils.getSubject();
            if (!subject.isPermitted("analysis:spc:view")) {
                return JsonPageResponseDto.FAILURE().setMessage(ExceptionMessages.EXCEPTION_NO_PERMISSION);
            }

            Map<String, Object> searchParam = Servlets.getParametersStartingWith(request, "search_");
            page = spcAnalysisService.searchDistinctTestItem(searchParam, PageUtil.buildPageWithParameters(request, systemConfig.getPageSize()));

        } catch (ApplicationException ex) {
            return JsonPageResponseDto.FAILURE().setMessage(ex.getMessage());
        }

        JsonPageResponseDto json = JsonPageResponseDto.SUCCESS().setBody(page.getContent());
        json.setRecordsTotal(page.getTotalElements());
        json.setRecordsFiltered(page.getTotalElements());
        json.setDraw(0);

        return json;
    }

    @ResponseBody
    @RequestMapping(value = "/slots")
    public JsonResponseDto slots(ServletRequest request, Model model) {
        Map<String, Object> searchParam = Servlets.getParametersStartingWith(request, "search_");

        List<BaseDto> list = spcAnalysisService.searchDistinctSlot(searchParam);

        return JsonResponseDto.SUCCESS().setBody(list);
    }

    @ResponseBody
    @RequestMapping(value = "/distinctSN")
    public JsonResponseDto distinctSN(ServletRequest request, Model model) {
        List<String> list = Lists.newArrayList();

        try {
            Map<String, Object> searchParam = Servlets.getParametersStartingWith(request, "search_");

            list = spcAnalysisService.searchDistinctSN(searchParam);
        } catch (Exception e) {
            return JsonResponseDto.FAILURE().setMessage(e.getMessage());
        }
        return JsonResponseDto.SUCCESS().setBody(list);
    }

    @ResponseBody
    @RequestMapping(value = "/analyseNDChart")
    public JsonResponseDto searchNormalDistribution(ServletRequest request, Model model) {
        Subject subject = SecurityUtils.getSubject();
        if (!subject.isPermitted("analysis:spc:view")) {
            return JsonResponseDto.FAILURE().setMessage(ExceptionMessages.EXCEPTION_NO_PERMISSION);
        }

        NormalDistributionDto dto = null;
        try {
            Map<String, Object> searchParam = Servlets.getParametersStartingWith(request, "search_");

            dto = spcAnalysisService.analyseNormalDistribution(searchParam);

        } catch (Exception e) {
            e.printStackTrace();
            return JsonResponseDto.FAILURE().setMessage(e.getMessage());
        }

        return JsonResponseDto.SUCCESS().setBody(dto);
    }

    @ResponseBody
    @RequestMapping(value = "/analyseRunChart")
    public JsonResponseDto searchRunControl(ServletRequest request, Model model) {
        Subject subject = SecurityUtils.getSubject();
        if (!subject.isPermitted("analysis:spc:view")) {
            return JsonResponseDto.FAILURE().setMessage(ExceptionMessages.EXCEPTION_NO_PERMISSION);
        }

        ControlDataDto dto = null;
        try {
            Map<String, Object> searchParam = Servlets.getParametersStartingWith(request, "search_");
            searchParam.put(Constant.ANALYSE_TYPE, Constant.ANALYSE_RUNC_TYPE);

            dto = spcAnalysisService.analyseControlChart(searchParam);

        } catch (ApplicationException e) {
            return JsonResponseDto.FAILURE().setMessage(e.getMessage());
        }

        return JsonResponseDto.SUCCESS().setBody(dto);
    }

    @ResponseBody
    @RequestMapping(value = "/analyseXBarChart")
    public JsonResponseDto searchMCC(ServletRequest request, Model model) {
        Subject subject = SecurityUtils.getSubject();
        if (!subject.isPermitted("analysis:spc:view")) {
            return JsonResponseDto.FAILURE().setMessage(ExceptionMessages.EXCEPTION_NO_PERMISSION);
        }

        ControlDataDto dto = null;
        try {
            Map<String, Object> searchParam = Servlets.getParametersStartingWith(request, "search_");
            searchParam.put(Constant.ANALYSE_TYPE, Constant.ANALYSE_XBARC_TYPE);

            dto = spcAnalysisService.analyseControlChart(searchParam);

        } catch (ApplicationException e) {
            return JsonResponseDto.FAILURE().setMessage(e.getMessage());
        }

        return JsonResponseDto.SUCCESS().setBody(dto);
    }

    @ResponseBody
    @RequestMapping(value = "/analyseSDChart")
    public JsonResponseDto searchStdCC(ServletRequest request, Model model) {
        Subject subject = SecurityUtils.getSubject();
        if (!subject.isPermitted("analysis:spc:view")) {
            return JsonResponseDto.FAILURE().setMessage(ExceptionMessages.EXCEPTION_NO_PERMISSION);
        }

        ControlDataDto dto = null;
        try {
            Map<String, Object> searchParam = Servlets.getParametersStartingWith(request, "search_");
            searchParam.put(Constant.ANALYSE_TYPE, Constant.ANALYSE_SDC_TYPE);

            dto = spcAnalysisService.analyseControlChart(searchParam);

        } catch (ApplicationException e) {
            return JsonResponseDto.FAILURE().setMessage(e.getMessage());
        }

        return JsonResponseDto.SUCCESS().setBody(dto);
    }

    @ResponseBody
    @RequestMapping(value = "/analyseRChart")
    public JsonResponseDto searchRgCC(ServletRequest request, Model model) {
        Subject subject = SecurityUtils.getSubject();
        if (!subject.isPermitted("analysis:spc:view")) {
            return JsonResponseDto.FAILURE().setMessage(ExceptionMessages.EXCEPTION_NO_PERMISSION);
        }
        ControlDataDto dto = null;
        try {
            Map<String, Object> searchParam = Servlets.getParametersStartingWith(request, "search_");
            searchParam.put(Constant.ANALYSE_TYPE, Constant.ANALYSE_RC_TYPE);

            dto = spcAnalysisService.analyseControlChart(searchParam);

        } catch (ApplicationException e) {
            return JsonResponseDto.FAILURE().setMessage(e.getMessage());
        }

        return JsonResponseDto.SUCCESS().setBody(dto);
    }

    @ResponseBody
    @RequestMapping(value = "/analyseMRChart")
    public JsonResponseDto searchMRgCC(ServletRequest request, Model model) {
        Subject subject = SecurityUtils.getSubject();
        if (!subject.isPermitted("analysis:spc:view")) {
            return JsonResponseDto.FAILURE().setMessage(ExceptionMessages.EXCEPTION_NO_PERMISSION);
        }
        ControlDataDto dto = null;
        try {
            Map<String, Object> searchParam = Servlets.getParametersStartingWith(request, "search_");
            searchParam.put(Constant.ANALYSE_TYPE, Constant.ANALYSE_MRC_TYPE);

            dto = spcAnalysisService.analyseControlChart(searchParam);

        } catch (ApplicationException e) {
            return JsonResponseDto.FAILURE().setMessage(e.getMessage());
        }

        return JsonResponseDto.SUCCESS().setBody(dto);
    }

//    @RequestMapping(value = "/export/spec/show")
//    public String exportSpecificShow(ServletRequest request, Model model) {
//        Subject subject = SecurityUtils.getSubject();
//        if (!subject.isPermitted("analysis:spc:export")) {
//            return "error/noPermission";
//        }
//        List<Object> datas = null;
//        try {
//            Map<String, Object> searchParam = Servlets.getParametersStartingWith(request, "search_");
//            String itemName = request.getParameter("itemName");
//            searchParam.put("itemName", itemName);
//            searchParam.put(Constant.ANALYSE_TYPE, Constant.ANALYSE_NDC_TYPE);
//            //datas = analysisCacheService.analyseNormalDistributionWithItems(searchParam);
//            JsonMapper mapper = new JsonMapper();
//            model.addAttribute("datas", mapper.toJson(datas));
//        } catch (ApplicationException e) {
//            return "";
//        }
//
//        return "analysis/spcExport";
//    }
//
//    @ResponseBody
//    @RequestMapping(value = "/export/spec/nd")
//    public JsonResponseDto exportSpecificND(ServletRequest request, Model model) {
//        Subject subject = SecurityUtils.getSubject();
//        if (!subject.isPermitted("analysis:spc:export")) {
//            return JsonResponseDto.FAILURE().setMessage(ExceptionMessages.EXCEPTION_NO_PERMISSION);
//        }
//
//        try {
//            Map<String, Object> searchParam = Servlets.getParametersStartingWith(request, "search_");
//            String itemName = request.getParameter("itemNames");
//            searchParam.put("itemNames", itemName);
//            String projectName = request.getParameter("projectName");
//            searchParam.put("projectName", projectName);
//            searchParam.put("fileType", "PDF");
//            spcExportService.exportNDChart2File(searchParam);
//        } catch (ApplicationException e) {
//            return JsonResponseDto.FAILURE().setMessage(e.getMessage());
//        }
//
//        return JsonResponseDto.SUCCESS();
//    }
//
//    @ResponseBody
//    @RequestMapping(value = "/export/single")
//    public JsonResponseDto exportSingleND(ServletRequest request, Model model) {
//        Subject subject = SecurityUtils.getSubject();
//        if (!subject.isPermitted("analysis:spc:export")) {
//            return JsonResponseDto.FAILURE().setMessage(ExceptionMessages.EXCEPTION_NO_PERMISSION);
//        }
//
//        try {
//            Map<String, Object> searchParam = Servlets.getParametersStartingWith(request, "search_");
//            spcExportService.exportExcel(searchParam);
//        } catch (ApplicationException e) {
//            return JsonResponseDto.FAILURE().setMessage(e.getMessage());
//        }
//
//        return JsonResponseDto.SUCCESS();
//    }

}
